package com.tony.blog.server.service.web.impl;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tony.blog.api.exception.CommonException;
import com.tony.blog.api.utils.Constant;
import com.tony.blog.model.entity.*;
import com.tony.blog.model.mapper.*;
import com.tony.blog.model.request.*;
import com.tony.blog.server.common.CommonService;
import com.tony.blog.server.lucene.LuceneBlogService;
import com.tony.blog.server.service.SysUserService;
import com.tony.blog.server.service.web.BlogService;
import com.tony.blog.server.service.web.IndexCenterService;
import com.tony.blog.server.service.web.UserMsgService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.CollectionUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 *
 * @Title: IndexCenterServiceImpl
 * @Auther: 皮蛋布丁
 * @Date: 2021/08/15/18:50
 * @Description:
 */
@Service
public class IndexCenterServiceImpl implements IndexCenterService {

    private static final Logger log = LoggerFactory.getLogger(IndexCenterServiceImpl.class);

    private static final Integer PageSize = 10;

    @Autowired
    private BlogService blogService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private Environment env;
    @Autowired
    private BlogMapper blogMapper;
    @Autowired
    private ConcernMapper concernMapper;
    @Autowired
    private CommonService commonService;
    @Autowired
    private BlogImageMapper blogImageMapper;
    @Autowired
    private PraiseMapper praiseMapper;
    @Autowired
    private CollectMapper collectMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private UserMsgService userMsgService;
    @Autowired
    private ReplyMapper replyMapper;
    @Autowired
    private LuceneBlogService luceneBlogService;

    /**
    * @Description: data 获取首页数据列表信息(向下滚动分页)
    * @Param: [paramMap]
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @Author: 皮蛋布丁
    * @Date: 2021/8/15 18:53
    */
    @Override
    public Map<String, Object> data(Map<String, Object> paramMap) throws Exception {
        Map<String,Object> resMap = Maps.newHashMap();

        paramMap.put(Constant.LIMIT,PageSize);
        paramMap.put(Constant.PAGE,paramMap.get("pageNo"));
        resMap.put("blogList",blogService.queryPage(paramMap));

        return resMap;
    }

    /**
    * @Description: getInfoByUserId 获取个人信息
    * @Param: [userId]
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @Author: 皮蛋布丁
    * @Date: 2021/8/19 20:00
    */
    @Override
    public Map<String, Object> getInfoByUserId(Long userId) {
        Map<String,Object> resMap = Maps.newHashMap();
        SysUserEntity entity = sysUserService.getById(userId);
        entity.setPassword(null);
        entity.setSalt(null);
        //设置用户头像
        if (StringUtils.isBlank(entity.getImgUrl())) {
            entity.setImgUrl(env.getProperty("common.user.img.default"));
        }
        if (entity.getImgUrl().startsWith("headPortrait") || entity.getImgUrl().startsWith(
                "miniBlog")) {
            entity.setImgUrl(env.getProperty("common.user.img.root.url")+entity.getImgUrl());
        } else {
            entity.setImgUrl(env.getProperty("common.file.access.root.url")+entity.getImgUrl());
        }
        //其他数据(关注数、粉丝数、微博数)
        resMap.put("blogTotal",blogMapper.countByUserId(userId.intValue()));
        resMap.put("fansTotal",concernMapper.countFansByUserId(userId.intValue()));
        resMap.put("concernsTotal",concernMapper.countConcernsByUserId(userId.intValue()));
        resMap.put("userInfo",entity);
        return resMap;
    }

    /**
    * @Description: uploadImg 上传微博图片
    * @Param: [request]
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @Author: 皮蛋布丁
    * @Date: 2021/8/21 23:16
    */
    @Override
    public Map<String, Object> uploadImg(MultipartHttpServletRequest request) throws Exception {
        Map<String, Object> resMap=Maps.newHashMap();

        MultipartFile multipartFile=request.getFile("img");
        //上传图片
        Map<String,Object> dataMap=commonService.uploadV2(multipartFile, SysModule.ModuleBlog,
                Constant.UpYunRootFolder.blog.getValue());

        BlogImage image = new BlogImage(String.valueOf(dataMap.get("fileName")),String.valueOf(dataMap.get("size")),
                String.valueOf(dataMap.get("suffix")),String.valueOf(dataMap.get("fileUrl")));
        blogImageMapper.insertSelective(image);

        resMap.put("imgId",image.getId());
        resMap.put("imgUrl",env.getProperty("common.file.upload.root.url")+dataMap.get("fileUrl"));

        return resMap;
    }

    /**
    * @Description: sendBlog 发送微博
    * @Param: [request, userId]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/8/24 23:07
    */
    @Override
    public Integer sendBlog(BlogRequest request, Long userId) throws Exception {
        //插入微博
        BlogEntity blog = new BlogEntity();
        blog.setContent(request.getContent());
        blog.setUserId(userId);
        blog.setType(1);
        blog.setCreateTime(DateTime.now().toDate());
        blogService.save(blog);

        //region 插入图片

        if (StringUtils.isNotBlank(request.getImgIds())) {
            String[] imgArr = StringUtils.split(request.getImgIds(),",");
            blogImageMapper.updateBlogByIds(blog.getId(), request.getImgIds());
        }

        //endregion
        //region 更新底层Lucene索引库的文档数据
        luceneBlogService.createDocument(blogMapper.selectByPK(blog.getId()));
        //endregion

        return 1;
    }

    /**
    * @Description: concernOn 关注
    * @Param: [request, entity]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/8/28 20:55
    */
    @Override
    public Integer concernOn(ConcernRequest request, SysUserEntity entity) {
        //根据关注者id和被关注者id获取关注的数量
        if (concernMapper.countByConcernBeId(entity.getUserId().intValue(),request.getBeConcernUserId()) <= 0) {
            if (!Objects.equals(request.getBeConcernUserId(),entity.getUserId().intValue())) {
                ConcernEntity concern = new ConcernEntity(entity.getUserId().intValue(),request.getBeConcernUserId(),
                        DateTime.now().toDate());
                int res = concernMapper.insertSelective(concern);
                //region 个人消息服务
                if (res > 0) {
                    userMsgService.concernMsg(request,entity,concern);
                }
                //endregion
                return res;
            }
        }
        return -1;
    }

    /**
    * @Description: concernCancel 取消关注
    * @Param: [request, userId]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/8/29 22:00
    */
    @Override
    public Integer concernCancel(ConcernRequest request, Long userId) {
        return concernMapper.deletebyConcernById(userId.intValue(),request.getBeConcernUserId());
    }

    /**
    * @Description: praiseOn 点赞
    * @Param: [request, entity]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/8/30 16:02
    */
    @Override
    public Integer praiseOn(OperationRequest request, SysUserEntity entity) {
        PraiseEntity praise = praiseMapper.selectByUserBlogId(request.getBlogId(),
                entity.getUserId());
        if (null != praise && praise.getStatus() == 1) {
            return 1;
        }
        if (null != praise) {
            //更新点赞
            praise.setStatus(1);
            praise.setUpdateTime(DateTime.now().toDate());
            praiseMapper.updateByPraimaryKeySelective(praise);
        } else {
            praise = new PraiseEntity(request.getBlogId(),entity.getUserId().intValue(),
                    DateTime.now().toDate(),1);
            praiseMapper.insertSelective(praise);
        }
        //region 个人消息服务
        BlogEntity srcBlog = blogMapper.selectByPK(request.getBlogId());
        if (!Objects.isNull(srcBlog) && !Objects.equals(entity.getUserId(),srcBlog.getUserId())) {
            userMsgService.praiseMsg(entity,srcBlog,praise);
        }
        //endregion
        return 1;
    }

    /**
    * @Description: praiseCancel 取消点赞
    * @Param: [request, userId]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/8/30 22:07
    */
    @Override
    public Integer praiseCancel(OperationRequest request, Long userId) {
        return praiseMapper.PraiseCancel(request.getBlogId(),userId,DateTime.now().toDate());
    }

    /**
    * @Description: collectOn 收藏
    * @Param: [request, userId]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/8/31 21:00
    */
    @Override
    public Integer collectOn(OperationRequest request, Long userId) {
        CollectEntity collect = collectMapper.selectByUserBlogId(request.getBlogId(),userId);
        if (null != collect && collect.getStatus() == 1) {
            return 1;
        }
        if (null != collect) {
            collect.setStatus(1);
            collect.setUpdateTime(DateTime.now().toDate());
            collectMapper.updateByPrimaryKeySelective(collect);
        } else {
            //收藏
            collect = new CollectEntity(request.getBlogId(),userId.intValue(),DateTime.now().toDate(),1);
            collectMapper.insertSelective(collect);
        }
        return 1;
    }

    /**
    * @Description: collectCancel 取消收藏
    * @Param: [request, userId]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/9/1 22:10
    */
    @Override
    public Integer collectCancel(OperationRequest request, Long userId) {
        return collectMapper.deleteByUserBlogId(request.getBlogId(),userId);
    }

    /**
    * @Description: commentOn 评论
    * @Param: [request, entity]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/9/5 20:50
    */
    @Override
    public Integer commentOn(CommentRequest request, SysUserEntity entity) {
        CommentEntity comment = new CommentEntity(request.getBlogId(),entity.getUserId().intValue(),
                request.getContent(),DateTime.now().toDate(),1);
        int res = commentMapper.insertSelective(comment);

        //region 个人消息提醒
        BlogEntity srcBlog = blogMapper.selectByPK(request.getBlogId());
        if (res >0 && !Objects.isNull(srcBlog) && !Objects.equals(srcBlog.getUserId(),entity.getUserId())) {
            userMsgService.commentMsg(request,comment.getId(),entity,srcBlog);
        }
        //endregion

        return res;
    }

    /**
    * @Description: deleteSelfBlog 删除微博
    * @Param: [request, entity]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/9/9 22:08
    */
    @Override
    public Integer deleteSelfBlog(IdRequest request, SysUserEntity entity) throws Exception {
        BlogEntity blog = blogMapper.selectByPK(request.getId());
        if (null != blog && Objects.equals(blog.getUserId(),entity.getUserId())) {
            int res = blogMapper.deleteById(request.getId());

            //更新底层IK索引库
            if (res > 0) {
                luceneBlogService.deleteDocument(request.getId());
            }
        }
        return -1;
    }

    /**
    * @Description: replyOn 回复微博(如果是评论，不需要传'被回复者'，否则需要传递被回复者的昵称)
    * @Param: [request, entity]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/9/10 11:13
    */
    @Override
    public Integer replyOn(ReplyRequest request, SysUserEntity entity) {
        CommentEntity comment = commentMapper.selectByPrimaryKey(request.getCommentId());
        if (null != comment && comment.getStatus().equals(1) && !Objects.equals(comment.getUserId(),entity.getUserId())) {
            ReplyEntity reply = new ReplyEntity(request.getBlogId(),request.getCommentId(),
                    entity.getUserId().intValue(),request.getContent(),entity.getName(),
                    DateTime.now().toDate(),1);
            int res = replyMapper.insertSelective(reply);

            //region 个人消息提醒
            if (res > 0 && !Objects.equals(entity.getUserId().intValue(),comment.getUserId())) {
                userMsgService.replyMsg(request,entity,reply.getId(),comment.getUserId());
            }
            //endregion
        }


        return 1;
    }

    /**
    * @Description: getCommentsByBlog 获取博文回复列表数据
    * @Param: [blogId]
    * @return: java.util.List<com.tony.blog.model.entity.CommentEntity>
    * @Author: 皮蛋布丁
    * @Date: 2021/9/10 11:44
    */
    @Override
    public List<CommentEntity> getCommentsByBlog(Integer blogId) {
        List<CommentEntity> list = commentMapper.selectByBlogId(blogId);
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(c -> {
                //遍历每一条评论数据，获取回复数据列表
                List<ReplyEntity> replies = replyMapper.selectByCommentId(c.getId());
                if (!CollectionUtils.isEmpty(replies)) {
                    replies.forEach(r -> {
                        //设置用户头像
                        if (StringUtils.isBlank(r.getHeaderImg())) {
                            r.setHeaderImg(env.getProperty("common.user.img.default"));
                        }
                        if (r.getHeaderImg().startsWith("headPortrait") || r.getHeaderImg().startsWith(
                                "miniBlog")) {
                            r.setHeaderImg(env.getProperty("common.user.img.root.url")+r.getHeaderImg());
                        } else {
                            r.setHeaderImg(env.getProperty("common.file.access.root.url")+r.getHeaderImg());
                        }
                    });
                }

                //设置评论下的回复数据
                c.setReplys(replies);
                //设置评论者的头像
                if (StringUtils.isBlank(c.getHeaderImg())) {
                    c.setHeaderImg(env.getProperty("common.user.img.default"));
                }
                if (c.getHeaderImg().startsWith("headPortrait") || c.getHeaderImg().startsWith(
                        "miniBlog")) {
                    c.setHeaderImg(env.getProperty("common.user.img.root.url")+c.getHeaderImg());
                } else {
                    c.setHeaderImg(env.getProperty("common.file.access.root.url")+c.getHeaderImg());
                }
            });
        }
        return list;
    }

    /**
    * @Description: forwardBlog 转发微博(type = 2的博文不能继续转发)
    * @Param: [request, entity]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/9/10 14:25
    */
    @Override
    public Integer forwardBlog(BlogForwardRequest request, SysUserEntity entity) throws Exception {
        //region 校验
        int total = blogService.countByForwardBlog(entity.getUserId(),request.getBlogId());
        if (total > 0) {
            throw new CommonException("您已经转发过该博文了,请勿重复转发!");
        }
        BlogEntity blog = blogService.getById(request.getBlogId());
        if (Objects.isNull(blog)) {
            throw new CommonException("待转发的博文已经不存在！");
        }
        if (Objects.equals(blog.getUserId(),entity.getUserId())) {
            throw new CommonException("不能转发自己的博文!");
        }
        if (Objects.equals(2,blog.getType())) {
            throw new CommonException("请找到最原始的博文再进行转发！");
        }
        //endregion
        //region 插入转发微博数据
        BlogEntity blogEntity = new BlogEntity();
        blogEntity.setContent(StringUtils.isNotBlank(request.getContent()) ?
                request.getContent() : "转发了...");
        blogEntity.setUserId(entity.getUserId());
        blogEntity.setType(2);
        blogEntity.setBlogId(request.getBlogId());
        blogEntity.setCreateTime(DateTime.now().toDate());
        Boolean res = blogService.save(blogEntity);
        //endregion
        //region 个人消息提醒
        if (res) {
            userMsgService.forwardMsg(entity,blogEntity,blog);

            //更新底层Lucene索引库的文档数据
            luceneBlogService.createDocument(blogMapper.selectByPK(blogEntity.getId()));
        }
        //endregion

        return 1;
    }

    /**
    * @Description: getBlogByUserId 我的博文
    * @Param: [paramMap]
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @Author: 皮蛋布丁
    * @Date: 2021/9/10 15:30
    */
    @Override
    public Map<String, Object> getBlogByUserId(Map<String, Object> paramMap) throws Exception {
        return this.data(paramMap);
    }

    /**
    * @Description: getMyPraisesBlog 我点赞的博文
    * @Param: [paramMap]
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @Author: 皮蛋布丁
    * @Date: 2021/9/10 16:08
    */
    @Override
    public Map<String, Object> getMyPraisesBlog(Map<String, Object> paramMap) throws Exception {
        Map<String,Object> resMap = Maps.newHashMap();
        paramMap.put(Constant.LIMIT,PageSize);
        paramMap.put(Constant.PAGE,paramMap.get("pageNo"));
        resMap.put("blogList",blogService.queryPagePraises(paramMap));
        return resMap;
    }

    /**
    * @Description: getMyCollectsBlog 获取我收藏的博文列表
    * @Param: [paramMap]
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @Author: 皮蛋布丁
    * @Date: 2021/9/16 10:08
    */
    @Override
    public Map<String, Object> getMyCollectsBlog(Map<String, Object> paramMap) throws Exception {
        Map<String,Object> resMap = Maps.newHashMap();
        paramMap.put(Constant.LIMIT,PageSize);
        paramMap.put(Constant.PAGE,paramMap.get("pageNo"));
        resMap.put("blogList",blogService.queryPageCollects(paramMap));

        return resMap;
    }

    /**
    * @Description: getMyFriendsBlog 获取我的朋友圈
    * @Param: [userId]
    * @return: java.util.List<com.tony.blog.model.entity.BlogEntity>
    * @Author: 皮蛋布丁
    * @Date: 2021/9/16 10:48
    */
    @Override
    public List<BlogEntity> getMyFriendsBlog(Long userId) {
        List<BlogEntity> list = Lists.newLinkedList();

        //region 方式一

        Set<Integer> friends = concernMapper.selectMyConcerns(userId.intValue());
        if (!CollectionUtils.isEmpty(friends)) {
            String userIds = Joiner.on(",").join(friends);
            list = blogMapper.selectBlogByUIds(userIds);
            //二次处理
            blogService.commonManageBlog(list);
        }

        //endregion

        return list;
    }

    /**
    * @Description: initLuceneData Lucene-数据初始化
    * @Param: []
    * @return: void
    * @Author: 皮蛋布丁
    * @Date: 2021/9/28 10:45
    */
    @Override
    public void initLuceneData() {
        //获取所有博文
        List<BlogEntity> list = blogMapper.selectAll();
        if (list != null && !list.isEmpty()) {
            list.forEach(blog -> {
                try {
                    luceneBlogService.createDocument(blog);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }

    /**
    * @Description: dataSearchLucene 首页全文检索-Lucene
    * @Param: [paramMap]
    * @return: java.util.Map<java.lang.String,java.lang.Object>
    * @Author: 皮蛋布丁
    * @Date: 2021/9/28 11:31
    */
    @Override
    public Map<String, Object> dataSearchLucene(Map<String, Object> paramMap) throws Exception {
        Map<String,Object> resMap = Maps.newHashMap();
        Integer pageNo = Integer.valueOf(Objects.isNull(paramMap.get("pageNo")) ? "1" :
                paramMap.get("pageNo").toString());

        if (paramMap.get("searchText") != null && StringUtils.isNotBlank(paramMap.get("searchText").toString())) {
            resMap.put("blogList",
                    luceneBlogService.searchDocumentPage(paramMap.get("searchText").toString(),
                            PageSize,pageNo));
        } else {
            resMap = this.data(paramMap);
        }
        return resMap;
    }
}
